package com.zwh.se.concurrency.threadLocal;

/**
 * @author zwh
 * ThreadLocal是Java中的一个类，它提供了一种线程本地变量的机制，使得每个线程都可以拥有自己的变量副本，互相之间不会产生干扰。
 * 可以理解为一个线程独有的存储空间，每个线程可以在其中存储自己的数据，而不用担心与其他线程的数据发生冲突。
 * 1、Thread中维护了一个ThreadLocalMap
 * 2、ThreadLocal本身不储存数据，像是一个工具类，基于ThreadLocal去操作ThreadLocalMap
 * 3、ThreadLocalMap本身是基于Entry[]实现的，因为一个线程可以绑定多个ThreadLocal，这样一来可能就需要储存多个数据，所以采用Entry[]方式实现
 * 4、每一个线程都具有一个独立的ThreadLocalMap，再基于ThreaLocal作为key，对value进行存储
 * 5、ThreadLocalMap的key是一个弱引用
 */
public class ThreadLocalDemo {
    static ThreadLocal t1 = new ThreadLocal();
    static ThreadLocal t2 = new ThreadLocal();
    public static void main(String[] args) throws InterruptedException {

        t1.set("111");
        t2.set("222");
        Thread thread =new Thread(()->{
            System.out.println(t1.get());
            System.out.println(t2.get());
        });
        thread.start();

        System.out.println("main:"+t1.get());
        System.out.println("main:"+t2.get());
        /**
         * ThreadLocalMap的内存泄露问题：
         * key的内存泄露：ThreadLocalMap中的key是ThreadLocal对象，如果ThreadLocal对象引用丢失，但是key的引用还在，那么这个ThreadLocal对象就不会被GC回收。
         * 解决方法：把key变成弱引用，这样只剩key引用ThreadLocal对象的话，GC会照样回收这个ThreadLocal对象
         * value的内存泄露：基于key是弱引用的情况，当key被回收了，value还在，这种情况导致了内存泄露
         * 解决方法：只需要在使用完ThreaLocal对象后，及时调用remove方法，移除Entry即可
         */
    }
}
